import json
import struct

from request_processor import RequestProcessor


class NetClient:
    def __init__(self, client_socket, address):
        self.client_socket = client_socket
        self.address = address
        self.received_json = None
    
    def receive_request(self):
        while True:
            try:
                # receive 4 bytes as length
                raw_length = self._recv_bytes(self.client_socket, 4)
                if not raw_length:
                    break
                msg_length = struct.unpack('<I', raw_length)[0]  # 小端整数
                # receive jason data
                raw_json = self._recv_bytes(self.client_socket, msg_length)
                json_str = raw_json.decode('utf-8')
                self.received_json = json.loads(json_str)
                
                processor = RequestProcessor(self.received_json)
                response = processor.process()
                if response:
                    self._send_json(self.client_socket, response)
                else:
                    pass
            except Exception as e:
                print(f"处理请求出错: {e}")
                break
        
        self.client_socket.close()
    
    def _recv_bytes(self, sock, length):
        """
        receive bytes of a specified length
        """
        data = b''
        while len(data) < length:
            chunk = sock.recv(length - len(data))
            if not chunk:
                return None
            data += chunk
        return data
    
    def _send_json(self, sock, json_obj):
        """
        serialize and send json object
        """
        json_str = json.dumps(json_obj)
        json_bytes = json_str.encode('utf-8')
        length_bytes = struct.pack('<I', len(json_bytes))  # 小端
        sock.sendall(length_bytes + json_bytes)
    
    def _send_error(self, sock, req_id, msg):
        response = {
            'id': req_id,
            'result': 'error',
            'error': msg
        }
        self._send_json(sock, response)
